package com.simple.microservices.commons.validator;

import com.simple.microservices.commons.annotation.EnumValid;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


/**
 * 枚举值校验器,可以校验输入的参数值是否为指定的枚举类型
 * 默认会取枚举中的code值与输入的参数值进行匹配
 */
@Component
public class EnumValidator implements ConstraintValidator<EnumValid, String> {

    /**
     * 需要校验的枚举类型
     */
    Class<?>[] enumCls;

    /**
     * 用枚举的哪一个方法值与参数值做校验
     */
    String codeValFieldName;

    @Override
    public void initialize(EnumValid constraintAnnotation) {
        this.enumCls = constraintAnnotation.target();
        this.codeValFieldName = constraintAnnotation.codeValFieldName();
    }


    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {

        if (enumCls.length > 0) {
            for (Class<?> enumCl : enumCls) {
                if (enumCl.isEnum()) {
                    //获取所有枚举对象
                    Object[] enumConstants = enumCl.getEnumConstants();
                    try {
                        for (Object enumConstant : enumConstants) {
                            //获取枚举值
                            Method code = enumConstant.getClass().getMethod(codeValFieldName);
                            Object enumVal = code.invoke(enumConstant);
                            if (enumVal.equals(value)) {
                                return true;
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        } else {
            return true;
        }
        return false;
    }

}
